/** @author temujin Nov 10, 2011 */
package paim.gh.model.pojos;


import javax.persistence.AccessType;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.OptimisticLockType;

import paim.wingchun.model.AField;
import paim.wingchun.model.Replicable;
import paim.wingchun.model.Validacao;
import paim.wingchun.model.modelos.ErroModel.Level;
import paim.wingchun.model.pojos.Pojo;

import paim.gh.model.Gradeavel;

/** @author temujin Nov 10, 2011 */

/** os fields referem se somente a esse periodo de turma
 *
 * @author paim 14/11/2011 */
@javax.persistence.Entity(access = AccessType.FIELD)
@org.hibernate.annotations.Entity(optimisticLock = OptimisticLockType.VERSION)
public class Periodo extends Pojo implements Replicable, Gradeavel {

    private static final long serialVersionUID = 1L;

    @AField(isHidden = true)
    @Validacao(nulo = Level.NENHUM)
    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(nullable = false)
    private Turma turma;

    @AField(isHidden = true)
    @Validacao(nulo = Level.NENHUM)
    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @JoinColumn(nullable = true)
    private Periodo anterior;

    @AField(isHidden = true)
    @Validacao(nulo = Level.NENHUM)
    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @JoinColumn(nullable = true)
    private Periodo posterior;

    /** professor somente desse periodo de turma */
    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(nullable = false)
    private Professor professor;

    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(nullable = false)
    private Horario horario;

    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(nullable = false)
    private Dia dia;

    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(nullable = false)
    private Sala sala;

    // @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    // @ManyToMany(targetEntity = Sala.class, fetch = FetchType.LAZY)
    // @JoinTable()
    // private List<Sala> salas = new ArrayList<>();

    /** indica que esse aulaparte nao pode ser alterado (data/horario) nas iteracoes,<BR>
     * por exemplo quando o usuario move manualmente TODO ou deveria setar em preferencias como obrigatorio?????? */
    // @Validacao(nulo = Level.ERRO$IMPEDITIVO)
    // @Column(nullable = false)
    private transient boolean fixo = false;

    public boolean isFixo() {
        return this.fixo;
    }

    public void setFixo(boolean fixo) {
        this.fixo = fixo;
    }

    public Sala getSala() {
        return sala;
    }

    public void setSala(Sala sala) {
        this.sala = sala;
    }

    public Dia getDia() {
        return this.dia;
    }

    public void setDia(Dia dia) {
        this.dia = dia;
    }

    public Horario getHorario() {
        return this.horario;
    }

    public void setHorario(Horario horario) {
        this.horario = horario;
    }

    public Professor getProfessor() {
        return this.professor;
    }

    public void setProfessor(Professor professor) {
        this.professor = professor;
    }

    public Periodo getAnterior() {
        return this.anterior;
    }

    public void setAnterior(Periodo anterior) {
        this.anterior = anterior;
    }

    public Periodo getPosterior() {
        return this.posterior;
    }

    public void setPosterior(Periodo posterior) {
        this.posterior = posterior;
    }

    public Turma getTurma() {
        return this.turma;
    }

    public void setTurma(Turma turma) {
        this.turma = turma;
    }

    @Override
    public Periodo replica() {
        Periodo replica = new Periodo();
        // TODO Auto-generated method stub
        return replica;
    }

    @Override
    public boolean equals(Object obj) {
        if ( !super.equals(obj) )
            return false;

        Periodo other = (Periodo) obj;

        if ( !equals(this.turma, other.turma) )
            return false;
        if ( !equals(this.professor, other.professor) )
            return false;
        if ( !equals(this.horario, other.horario) )
            return false;
        if ( !equals(this.dia, other.dia) )
            return false;
        if ( !equals(this.sala, other.sala) )
            return false;

        return true;
    }

}
